home *** CD-ROM | disk | FTP | other *** search
- Path: news.belwue.de!uzwil!kuehl
- From: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl)
- Newsgroups: comp.lang.c++,gnu.g++.help
- Subject: Re: DONT UNDERSTAND - array of char error
- Followup-To: comp.lang.c++,gnu.g++.help
- Date: 2 Mar 1996 22:20:46 GMT
- Organization: FakultΣt fⁿr Mathematik und Informatik
- Message-ID: <4hahju$bil@news.BelWue.DE>
- References: <4habvu$99j@panix.com>
- Reply-To: dietmar.kuehl@uni-konstanz.de
- NNTP-Posting-Host: uzwil.informatik.uni-konstanz.de
- X-Newsreader: TIN [version 1.2 PL2]
-
- Hi,
- Arthur Cinader Jr (acinader@panix.com) wrote:
- : char *labels[];
- : char *params[];
-
- : the compiler, g++, gave me the following error:
-
- : param.h:21: field `labels' has incomplete type
-
- : I don't understand why this doesn't work.
-
- You want to allocate an object whose size is unknown. This is always
- impossible in C++. You can, however, pass around "handle" to an object
- whose size is unknown, e.g. a pointer to an array:
-
- void foo(char *argv[]) {} // legal
-
- If you want to actually allocate an object, the size of the object has
- to be known, e.g. in a definition like this:
-
- const int size = 17;
- char *labels[size];
-
- where 'size' is always a constant expression (i.e. it is NOT possible
- to use some variable for size, whose value is determined at run-time).
-
- : In any event, I changed the declaration to:
-
- : char **labels;
- : char **params;
-
- : Which the compiler liked.
-
- Sure, because it knows the size of the object: a pointer to pointer to
- 'char' is probably four bytes (you can use 'sizeof(char**)' to find
- out).
-
- : Now, I am unable to new the arrays.
-
- Well, because you forgot about an important restriction on arrays: All
- but the first dimension has to be fixed at compile-time.
-
- : In the definition (.C) file, I use the comand:
-
- : labels = new char[maxargs][fieldlength]; // make label array
- : params = new char[maxargs][fieldlength]; // make params array
-
- ... i.e. 'fieldlength' has to be a 'const'. If 'fieldlength' is
- non-const you have to allocate the second dimension by hand (unless you
- use an array class like suggested below):
-
- lables = new char *[maxargs]; // it is valid to allocate an array
- params = new char *[maxargs]; // of 'char*'
- for (int i = 0; i < maxargs; i++)
- {
- labels[i] = new char[fieldlength]; // ... and to allocate an
- params[i] = new char[fieldlength]; // of 'char'.
- }
-
- ... but an array thus create has to be destructed like this:
-
- for (int i = maxargs; i--; )
- {
- delete[] params[i];
- delete[] lables[i];
- }
- delete params;
- delete lables;
-
- Which is, IMHO, far to dangerous to be done: Given that you run out of
- memory, you are likely to end up with a serious memory-leak. I know how
- to program in C++ and I won't do it like this... This is exactly the
- problem I have with all C++ tutorials I have seen until know: They
- introduce the low-level methods, requiring to be an expert to handle
- them correctly, but they don't introduce the clean methods provided by
- the (upcoming) ISO Standard C++ Library (to be fair: this library was
- introduced into the standard quite recently, i.e. sometime in 1994). A
- clean method is to use the 'vector' class found in libg++ starting with
- libg++-2.6.? (you didn't mention what version you are using but I
- assume a recent one, e.g. 2.7.2):
-
- void f(int maxargs, int fieldlength)
- {
- vector<vector<char> > labels(maxargs, vector<char>(fieldlength));
- vector<vector<char> > labels(maxargs, vector<char>(fieldlength));
- // ...
- // Note that the compiler takes care of destruction...
- }
-
- It is even possible to resize these 'vector' (something impossible with
- built-in arrays). I suggest, that you use 'vector' instead of built-in
- arrays...
-
- : The compiler complains with the following:
-
- : param.C: In method `Param::Param(char *)':
- : param.C:11: assignment to `char **' from `char (*)[1]'
- : param.C:16: assignment to `char **' from `char (*)[1]'
-
- : I do not understand why?
-
- Well, the compiler knows that he can only allocate an array with one
- dimension being variable i.e. it assumes that 'char[maxargs]' is a type
- (the '[fieldlength]' could not be append and the stuff still be a type)
- and thus interprets the expression 'new char[maxargs][fieldlength]' as
- '(new char[maxargs])[fieldlength]'. This allocates an array of 'char'
- and applies the "index operator" ([]) to it with 'fieldlength' as
- arguemtn. Thus the value of the whole expression is the 'fieldlength`'
- element of the just allocated array. This is, probably, not what you
- want...
-
- : P.S. do the deletes in my destructor look kosher?
-
- Well, it is only half the way to be done... See my code example above
- for a complete deallocation of a hand-crafted two-dimensional array
- with variable bounds.
- --
- dietmar.kuehl@uni-konstanz.de
- http://www.informatik.uni-konstanz.de/~kuehl
- I am a realistic optimist - that's why I appear to be slightly pessimistic
-